"""
通义万相图像生成服务
"""
import httpx
import asyncio
import json
from typing import List, Optional
from app.config import settings, app_config
from app.utils.logger import logger
from app.utils.exceptions import ImageGenerationError


class TongyiImageService:
    """通义万相图像生成服务类"""
    
    def __init__(self):
        self.api_key = settings.tongyi_api_key
        self.base_url = settings.tongyi_base_url
        self.config = app_config.tongyi
        self.headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json",
            "X-DashScope-Async": "enable"
        }
    
    async def _make_request(self, prompt: str) -> str:
        """发送图像生成请求"""
        url = f"{self.base_url}/api/v1/services/aigc/text2image/image-synthesis"
        
        data = {
            "model": self.config["model"],
            "input": {
                "prompt": prompt
            },
            "parameters": {
                "size": self.config["size"],
                "n": 1
            }
        }
        
        try:
            async with httpx.AsyncClient(timeout=60.0) as client:
                response = await client.post(url, json=data, headers=self.headers)
                response.raise_for_status()
                
                result = response.json()
                logger.info(f"通义万相API响应: {json.dumps(result, ensure_ascii=False)}")
                
                # 检查是否是异步任务
                if result.get("output", {}).get("task_status") == "PENDING":
                    task_id = result["output"]["task_id"]
                    return await self._wait_for_completion(task_id)
                
                # 同步返回结果
                if "output" in result and "results" in result["output"]:
                    image_url = result["output"]["results"][0]["url"]
                    logger.info(f"通义万相图像生成成功: {image_url}")
                    return image_url
                else:
                    raise ImageGenerationError("通义万相API返回格式异常")
                    
        except httpx.HTTPStatusError as e:
            error_detail = f"HTTP {e.response.status_code}: {e.response.text[:500]}"
            logger.error(f"通义万相API HTTP错误详情: {error_detail}")
            logger.error(f"请求URL: {url}")
            logger.error(f"请求数据: {data}")
            logger.error(f"请求头: {self.headers}")
            raise ImageGenerationError(f"通义万相API调用失败: HTTP {e.response.status_code}")
        except Exception as e:
            import traceback
            error_traceback = traceback.format_exc()
            logger.error(f"通义万相API调用异常详情:")
            logger.error(f"错误类型: {type(e).__name__}")
            logger.error(f"错误信息: {str(e)}")
            logger.error(f"请求URL: {url}")
            logger.error(f"请求数据: {data}")
            logger.error(f"完整堆栈信息:\n{error_traceback}")
            raise ImageGenerationError(f"通义万相API调用异常: {e}")
    
    async def _wait_for_completion(self, task_id: str, max_wait_time: int = 300) -> str:
        """等待异步任务完成"""
        url = f"{self.base_url}/api/v1/tasks/{task_id}"
        
        wait_time = 0
        while wait_time < max_wait_time:
            try:
                async with httpx.AsyncClient(timeout=30.0) as client:
                    response = await client.get(url, headers=self.headers)
                    response.raise_for_status()
                    
                    result = response.json()
                    status = result.get("output", {}).get("task_status")
                    
                    if status == "SUCCEEDED":
                        image_url = result["output"]["results"][0]["url"]
                        logger.info(f"异步任务完成，图像URL: {image_url}")
                        return image_url
                    elif status == "FAILED":
                        error_msg = result.get("output", {}).get("message", "未知错误")
                        raise ImageGenerationError(f"图像生成失败: {error_msg}")
                    elif status == "PENDING" or status == "RUNNING":
                        logger.info(f"任务 {task_id} 正在处理中，状态: {status}")
                        await asyncio.sleep(5)
                        wait_time += 5
                    else:
                        raise ImageGenerationError(f"未知任务状态: {status}")
                        
            except httpx.HTTPStatusError as e:
                logger.error(f"查询任务状态失败: {e.response.status_code} - {e.response.text}")
                raise ImageGenerationError(f"查询任务状态失败: {e}")
        
        raise ImageGenerationError(f"任务 {task_id} 等待超时")
    
    async def generate_image(self, prompt: str) -> str:
        """生成单张图片"""
        # 优化提示词，添加高质量描述
        enhanced_prompt = f"{prompt}，高质量，清晰，美观，专业"
        
        logger.info(f"开始生成图片，提示词: {enhanced_prompt}")
        image_url = await self._make_request(enhanced_prompt)
        return image_url
    
    async def generate_cover_image(self, title: str, description: str) -> str:
        """生成封面图片"""
        prompt = f"微信公众号封面图，{description}，标题相关：{title}，简洁现代，商务风格，16:9比例"
        
        logger.info(f"生成封面图片: {prompt}")
        return await self.generate_image(prompt)
    
    async def generate_content_images(self, descriptions: List[str]) -> List[str]:
        """批量生成内容配图"""
        image_urls = []
        
        for i, description in enumerate(descriptions):
            try:
                prompt = f"文章配图，{description}，插图风格，清晰美观，适合公众号文章"
                logger.info(f"生成第{i+1}张配图: {prompt}")
                
                image_url = await self.generate_image(prompt)
                image_urls.append(image_url)
                
                # 添加延迟避免请求过于频繁
                if i < len(descriptions) - 1:
                    await asyncio.sleep(2)
                    
            except Exception as e:
                logger.error(f"生成第{i+1}张配图失败: {str(e)}")
                # 继续生成其他图片，不中断整个流程
                continue
        
        logger.info(f"批量生成配图完成，成功: {len(image_urls)}/{len(descriptions)}")
        return image_urls
    
    async def download_image(self, image_url: str) -> bytes:
        """下载图片数据"""
        try:
            async with httpx.AsyncClient(timeout=30.0) as client:
                response = await client.get(image_url)
                response.raise_for_status()
                
                image_data = response.content
                logger.info(f"图片下载成功，大小: {len(image_data)} bytes")
                return image_data
                
        except Exception as e:
            logger.error(f"图片下载失败: {str(e)}")
            raise ImageGenerationError(f"图片下载失败: {e}")
    
    def optimize_prompt_for_wechat(self, original_prompt: str) -> str:
        """优化提示词以适合微信公众号"""
        # 添加微信公众号相关的风格描述
        wechat_keywords = [
            "商务风格",
            "现代简约",
            "专业质感",
            "清晰明亮",
            "适合移动端查看",
            "16:9横版布局"
        ]
        
        optimized = f"{original_prompt}，{', '.join(wechat_keywords[:2])}"
        return optimized


# 全局服务实例
tongyi_service = TongyiImageService()